using System;
using System.IO;

namespace MultiplayerARPG.MMO
{
    namespace LCLib.Asn1Processor
    {
        /// <summary>
        /// Summary description for Util.
        /// </summary>
        internal class Asn1Util
        {
            public static int BytePrecision(ulong value)
            {
                int i;
                for (i = sizeof(ulong); i > 0; --i)
                    if ((value >> (i - 1) * 8) != 0)
                        break;
                return i;
            }

            public static int DERLengthEncode(Stream xdata, ulong length)
            {
                int i = 0;
                if (length <= 0x7f)
                {
                    xdata.WriteByte((byte)length);
                    i++;
                }
                else
                {
                    xdata.WriteByte((byte)(BytePrecision(length) | 0x80));
                    i++;
                    for (int j = BytePrecision((ulong)length); j > 0; --j)
                    {
                        xdata.WriteByte((byte)(length >> (j - 1) * 8));
                        i++;
                    }
                }
                return i;
            }

            public static long DerLengthDecode(Stream bt)
            {
                long length = 0;
                byte b;
                b = (byte)bt.ReadByte();
                if ((b & 0x80) == 0)
                {
                    length = b;
                }
                else
                {
                    long lengthBytes = b & 0x7f;
                    if (lengthBytes == 0)
                    {
                        throw new Exception("Indefinite length.");
                    }
                    length = 0;
                    while (lengthBytes-- > 0)
                    {
                        if ((length >> (8 * (sizeof(long) - 1))) > 0)
                            throw new Exception("Length overflow.");
                        b = (byte)bt.ReadByte();
                        length = (length << 8) | b;
                    }
                }
                return length;
            }

            private Asn1Util()
            {
            }

        }
    }
}